home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / Xconq 7.0d16 / Xconq 7.0d16 src / src / unit.c < prev    next >
Encoding:
Text File  |  1993-12-20  |  41.3 KB  |  158 lines  |  [TEXT/MPS ]

  1. /* Copyright (c) 1987-1993  Stanley T. Shebs. */
  2. /* This program may be used, copied, modified, and redistributed freely */
  3. /* for noncommercial purposes, so long as this notice remains intact. */
  4.  
  5. /* This file contains all code that manages units. */
  6.  
  7. #include "conq.h"
  8.  
  9. void leave_hex_aux();
  10.  
  11. /* This is not a limit, just sets initial allocation of unit objects
  12.    and how many additional to get if more are needed.  Should be tuned
  13.    for the system. */
  14.  
  15. #ifndef INITMAXUNITS
  16. #define INITMAXUNITS 200
  17. #endif
  18.  
  19. ursively. */
  20.     for_all_occupants(unit, occ) {
  21.     enter_hex_aux(occ, x, y);
  22.     }
  23. }
  24.  
  25. /* Decide whether the given unit can actually be in the given transport. */
  26.  
  27. /* (this still needs to account for multipart units) */
  28.  
  29. can_occupy(unit, transport)
  30. Unit *transport, *unit;
  31. {
  32.     return can_carry(transport, unit);
  33. }
  34.  
  35. can_carry(transport, unit)
  36. Unit *transport, *unit;
  37. {
  38.     int u = unit->type, u2 = transport->type;
  39.     int numthistype = 0, numalltypes = 0, occvolume = 0;
  40.     int ucap, uucap;
  41.     Unit *occ;
  42.  
  43.     /* Intercept nonsensical arguments. */
  44.     if (transport == unit) return FALSE;
  45. /*    if (!completed(transport)) return FALSE;  */
  46.     if (unit->occupant != NULL && !uu_occ_can_have_occs(u, u2)) return FALSE;
  47.     ucap = u_capacity(u2);
  48.     uucap = uu_capacity_x(u2, u);
  49.     if (ucap <= 0 && uucap <= 0) return FALSE;
  50.     /* Compute the transport's fullness. */
  51.     for_all_occupants(transport, occ) {
  52.     if (occ->type == u) ++numthistype;
  53.     ++numalltypes;
  54.     occvolume += uu_size(occ->type, u2);
  55.     }
  56.     /* Can carry if dedicated space available. */
  57.     if (numthistype + 1 <= uucap) return TRUE;
  58.     /* Check upper limit on count of occupants. */
  59.     if (uu_occ_max(u2, u) >= 0
  60.         && numthistype + 1 - uucap > uu_occ_max(u2, u)) return FALSE;
  61.     if (u_occ_total_max(u2) >= 0
  62.         && numalltypes + 1 > u_occ_total_max(u2)) return FALSE;
  63.     /* Can carry if general unit hold has room. */
  64.     return (occvolume + uu_size(u, u2) <= ucap);
  65. }
  66.  
  67. type_can_occupy(u, transport)
  68. int u;
  69. Unit *transport;
  70. {
  71.     int u2 = transport->type;
  72.     int numthistype = 0, numalltypes = 0, occvolume = 0;
  73.     int ucap, uucap;
  74.     Unit *occ;
  75.  
  76.     if (!completed(transport)) return FALSE;
  77.     ucap = u_capacity(u2);
  78.     uucap = uu_capacity_x(u2, u);
  79.     if (ucap <= 0 && uucap <= 0) return FALSE;
  80.     /* Compute the transport's fullness. */
  81.     for_all_occupants(transport, occ) {
  82.     if (occ->type == u) ++numthistype;
  83.     ++numalltypes;
  84.     occvolume += uu_size(occ->type, u2);
  85.     }
  86.     /* Can carry if dedicated space available. */
  87.     if (numthistype + 1 <= uucap) return TRUE;
  88.     if (uu_occ_max(u2, u) >= 0
  89.         && numthistype + 1 - uucap > uu_occ_max(u2, u))
  90.       return FALSE;
  91.     if (u_occ_total_max(u2) >= 0
  92.         && numalltypes + 1 > u_occ_total_max(u2)) return FALSE;
  93.     /* Can carry if general unit hold has room. */
  94.     return (occvolume + uu_size(u, u2) <= ucap);
  95. }
  96.  
  97. can_occupy_type(unit, u2)
  98. Unit *unit;
  99. int u2;
  100. {
  101.     int u = unit->type;
  102.  
  103.     /* Can occupy if nonzero reserved capacity for this type. */
  104.     if (uu_capacity_x(u2, u) > 0) return TRUE;
  105.     /* Can occupy if general unit hold has room for at least one unit. */
  106.     return (uu_size(u, u2) <= u_capacity(u2));
  107. }
  108.  
  109. can_carry_type(transport, u)
  110. Unit *transport;
  111. int u;
  112. {
  113.     return type_can_occupy(u, transport);
  114. }
  115.  
  116. /* Units become occupants by linking into the transport's occupant list. */
  117.  
  118. void
  119. enter_transport(unit, transport)
  120. Unit *unit, *transport;
  121. {
  122.     int u = unit->type, ustack, u2stack;
  123.     Unit *unit2, *topunit = transport->occupant;
  124.     Unit *prevunit = NULL, *nextunit = NULL;
  125.  
  126.     if (unit == transport) {
  127.         run_error("Unit is trying to enter itself");
  128.     }
  129.     if (topunit) {
  130.         /* Insert the entering unit into the occupant list at
  131.        its correct position. */
  132.         ustack = u_stack_order(u);
  133.         for_all_occupants(transport, unit2) {
  134.         u2stack = u_stack_order(unit2->type);
  135.         if (ustack > u2stack
  136.         || (ustack == u2stack && unit->id < unit2->id)) {
  137.         nextunit = unit2;
  138.         if (unit2 == topunit) topunit = unit;
  139.         break;
  140.         }
  141.         prevunit = unit2;
  142.         }
  143.         if (prevunit != NULL) prevunit->nexthere = unit;
  144.     } else {
  145.         topunit = unit;
  146.     }
  147.     unit->nexthere = nextunit;
  148.     transport->occupant = topunit;
  149.     /* Point from the unit back to its transport. */
  150.     unit->transport = transport;
  151.     /* Set the passenger's coords to match the transport's. */
  152.     enter_hex_aux(unit, transport->x, transport->y);
  153.     /* Others might be watching. */
  154.     all_see_occupy(unit, transport->x, transport->y, FALSE);
  155. }
  156.  
  157. /* Unit departs from a hex by zeroing out pointer if in hex or by being
  158.    remov